package com.hunliji.monitor.manager.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hunliji.common.exception.WarnException;
import com.hunliji.monitor.manager.api.FeishuInterceptionManager;
import com.hunliji.monitor.manager.config.FeishuProjectConfig;
import com.lark.project.core.Config;
import com.lark.project.core.request.RequestOptions;
import com.lark.project.core.token.GlobalTokenManager;
import com.lark.project.service.view.ViewService;
import com.lark.project.service.view.builder.WorkItemListReq;
import com.lark.project.service.view.builder.WorkItemListResp;
import com.lark.project.service.workitem.WorkItemService;
import com.lark.project.service.workitem.builder.FilterResp;
import com.lark.project.service.workitem.builder.QueryWorkItemDetailReq;
import com.lark.project.service.workitem.builder.QueryWorkItemDetailReqBody;
import com.lark.project.service.workitem.builder.QueryWorkItemDetailResp;
import com.lark.project.service.workitem.model.WorkItemInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class FeishuInterceptionManagerImpl implements FeishuInterceptionManager {

    @Resource
    private WorkItemService workItemService;

    @Resource
    private ViewService viewService;

    @Resource
    private Config config;

    @Resource
    private FeishuProjectConfig feishuProjectConfig;


    @Override
    public String getAccessToken() {
        String accessToken;
        try {
            accessToken = GlobalTokenManager.getTokenManager().getAccessTokenThenCache(config);
            return accessToken;
        } catch (Exception e) {
            throw new WarnException("获取accessToken失败");
        }
    }

    @Override
    public Long getWorkItemId(String accessToken, String projectKey, List<String> workItemTypeKeys, String workItemName) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.put("X-PLUGIN-TOKEN", Lists.newArrayList(accessToken));
        headers.put("X-USER-KEY", Lists.newArrayList(feishuProjectConfig.getUserKey()));

        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("work_item_type_keys", workItemTypeKeys);
        paramMap.put("work_item_name", workItemName);
        HttpEntity<Map<String, Object>> mapHttpEntity = new HttpEntity<>(paramMap, headers);
        String url = "https://project.feishu.cn/open_api/" + projectKey + "/work_item/filter";

        try {
            ResponseEntity<FilterResp> response = restTemplate.postForEntity(url, mapHttpEntity, FilterResp.class);
            if (!HttpStatus.OK.equals(response.getStatusCode())) {
                return null;
            }
            FilterResp filterResp = response.getBody();
            if (filterResp == null || filterResp.getErrCode() != 0) {
                log.warn("获取工作项失败 filterResp={}", filterResp);
                return null;
            }
            List<WorkItemInfo> workItemInfoList = filterResp.getData();
            if (CollectionUtils.isEmpty(workItemInfoList)) {
                log.warn("获取工作项失败，filterResp={}", filterResp);
                return null;
            }
            WorkItemInfo workItemInfo;
            if (workItemInfoList.size() == 1) {
                return workItemInfoList.get(0).getID();
            }
            workItemInfo = workItemInfoList.stream()
                    .sorted(Comparator.comparing(WorkItemInfo::getCreatedAt).reversed())
                    .filter(itemInfo -> workItemName.equals(itemInfo.getName()))
                    .findFirst()
                    .orElse(null);
            if (workItemInfo == null) {
                log.warn("获取工作项失败，filterResp={}", filterResp);
                return null;
            }
            return workItemInfo.getID();
        }catch (Exception e) {
            log.warn("获取结果异常", e);
            return null;
        }
    }

    @Override
    public WorkItemInfo getWorkItemInfo(String accessToken, Long workItemId, String projectKey, String workItemTypeKey) {
        QueryWorkItemDetailReq req = new QueryWorkItemDetailReq();
        req.setProjectKey(projectKey);
        req.setWorkItemTypeKey(workItemTypeKey);
        QueryWorkItemDetailReqBody paramBody = new QueryWorkItemDetailReqBody();
        paramBody.setWorkItemIDs(com.lark.project.core.utils.Lists.newArrayList(workItemId));
        req.setQueryWorkItemDetailReqBody(paramBody);

        RequestOptions requestOptions = getRequestOption(accessToken, feishuProjectConfig.getUserKey());
        try {
            QueryWorkItemDetailResp queryWorkItemDetailResp = workItemService.queryWorkItemDetail(req, requestOptions);
            return queryWorkItemDetailResp.getData().get(0);
        } catch (Exception e) {
            log.warn("获取工作项失败", e);
            return null;
        }
    }

    @Override
    public List<Long> viewWorkItemList(String accessToken, String projectKey, String viewId) {
        WorkItemListReq req = new WorkItemListReq();
        req.setProjectKey(projectKey);
        req.setPageNum(1L);
        req.setPageSize(200L);
        req.setViewID(viewId);

        RequestOptions requestOptions = getRequestOption(accessToken, feishuProjectConfig.getUserKey());
        try {
            WorkItemListResp workItemListResp = viewService.workItemList(req, requestOptions);
            return workItemListResp.getData().getWorkItemIDList();
        } catch (Exception e) {
            log.warn("获取视图下工作项失败", e);
            return Lists.newArrayList();
        }
    }

    private RequestOptions getRequestOption(String accessToken, String userKey) {
        RequestOptions requestOptions = new RequestOptions();
        Map<String, List<String>> headers = new HashMap<>();
        headers.put("X-PLUGIN-TOKEN", Lists.newArrayList(accessToken));
        headers.put("X-USER-KEY", Lists.newArrayList(userKey));
        requestOptions.setHeaders(headers);
        return requestOptions;
    }
}
